package com.mingqijia.gassafety.job.job.warnStrategy;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gap.cache.redis.RedisCache;
import com.mingqijia.gassafety.db.entity.BusinessNotice;
import com.mingqijia.gassafety.db.entity.Consumer;
import com.mingqijia.gassafety.db.entity.DeviceState;
import com.mingqijia.gassafety.db.entity.Dtu;
import com.mingqijia.gassafety.db.entity.JvInfo;
import com.mingqijia.gassafety.db.entity.WarnStrategy;
import com.mingqijia.gassafety.db.entity.WarnStrategyExt;
import com.mingqijia.gassafety.db.mapper.BusinessNoticeMapper;
import com.mingqijia.gassafety.db.mapper.ConsumerMapper;
import com.mingqijia.gassafety.db.mapper.ContactsMapper;
import com.mingqijia.gassafety.db.mapper.CustomerSubsMapper;
import com.mingqijia.gassafety.db.mapper.DeviceStateMapper;
import com.mingqijia.gassafety.db.mapper.DictionaryMapper;
import com.mingqijia.gassafety.db.mapper.DtuBindingOrderMapper;
import com.mingqijia.gassafety.db.mapper.DtuMapper;
import com.mingqijia.gassafety.db.mapper.JvInfoMapper;
import com.mingqijia.gassafety.db.mapper.ReceiverValveMapper;
import com.mingqijia.gassafety.db.mapper.RecordReceiverValveMapper;
import com.mingqijia.gassafety.db.mapper.WarnStrategyExtMapper;
import com.mingqijia.gassafety.db.mapper.WarnStrategyMapper;
import com.mingqijia.gassafety.db.mapper.WarningRecordMapper;
import com.mingqijia.gassafety.job.dto.PredateStrategyDTO;
import com.mingqijia.gassafety.job.dto.SendMessageDTO;
import com.mingqijia.gassafety.job.service.ConsumerService;
import com.mingqijia.gassafety.job.service.impl.CallTaskServiceImpl;
import com.mingqijia.gassafety.job.service.impl.CompanyServiceImpl;
import com.mingqijia.gassafety.job.service.impl.DevicebindingServiceImpl;
import com.mingqijia.gassafety.job.service.impl.EquipmentServiceImpl;
import com.mingqijia.gassafety.job.service.impl.WarningRecordServiceImpl;
import com.mingqijia.gassafety.job.strategy.MessageContext;
import com.mingqijia.gassafety.job.strategy.PredicateGasWarnContext;
import com.mingqijia.gassafety.job.strategy.RecordService;
import com.mingqijia.gassafety.shared.constant.Constants;
import com.mingqijia.gassafety.shared.constant.EquipmentType;
import com.mingqijia.gassafety.shared.utils.RedisCacheExt;
import com.mingqijia.gassafety.shared.utils.commonUtils.SnowflakeUtil;
import com.mingqijia.gassafety.shared.utils.message.SendMessageService;
import com.mingqijia.gassafety.shared.vcc.VccAuthoritiesProvider;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.ConvertingCursor;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * @author zhangfei
 * @version 1.0.0
 * @ClassName WarnStrategyV2Job.java
 * @Description
 * @createTime 2022年02月28日
 */

@Component
@Slf4j
public class WarnStrategyClearJob {

    @Autowired
    RedisCache redisCache;
    @Autowired
    ConsumerMapper consumerMapper;
    @Autowired
    CustomerSubsMapper customerSubsMapper;
    @Autowired
    DtuMapper dtuMapper;
    @Autowired
    WarnStrategyExtMapper warnStrategyExtMapper;
    @Autowired
    ContactsMapper contactsMapper;
    @Autowired
    SendMessageService sendMessageService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    DictionaryMapper dictionaryMapper;
    @Autowired
    WarnStrategyMapper warnStrategyMapper;
    @Autowired
    WarningRecordMapper warningRecordMapper;
    @Autowired
    WarningRecordServiceImpl warningRecordService;
    @Autowired
    EquipmentServiceImpl equipmentService;
    @Autowired
    CompanyServiceImpl companyService;

    @Autowired
    DevicebindingServiceImpl devicebindingService;
    @Autowired
    BusinessNoticeMapper noticeMapper;

    @Autowired
    ReceiverValveMapper receiverValveMapper;


    @Autowired
    MessageContext messageContext;

    @Autowired
    PredicateGasWarnContext predicateGasWarnContext;

    @Autowired
    RecordService warnRecordService;


    public static final String split = ";";
    public static final String split_ = "-";

    //需要匹配的key
    private String patternKey = Constants.WARNING_EQUIPMENT + ":*";

    public static final String CM_SERVICE_HOT_LINE="cm_service_hot_line";

    public static final Integer pageSize = 1000;

    @Value(value = "${gassafety.warnStrategy.switch}")
    private boolean sw;
    @Autowired
    RedisCacheExt redisUtil;

    @Autowired
    VccAuthoritiesProvider provider;

    @Autowired
    DeviceStateMapper deviceStateMapper;
    @Autowired
    DtuBindingOrderMapper dtuBindingOrderMapper;
    @Autowired
    ConsumerService consumerService;
    @Autowired
    CallTaskServiceImpl callTaskService;
    @Autowired
    RecordReceiverValveMapper  recordReceiverValveMapper;

    @Autowired
    JvInfoMapper jvInfoMapper;

    /**
     * 燃气泄漏报警策略 再次预警: 一分钟一次：0 0/1 * * * ?
     */
    @XxlJob("warnStrategyClear")
    public ReturnT<String> warnStrategyAgain(String param) {
        XxlJobLogger.log("XXLJOB-warnStrategyClear start..." );
        log.info("warnStrategyClear--start--------");

        // 燃气泄漏报警策略开关
        if (!sw) return ReturnT.SUCCESS;
        // 燃气泄漏报警策略再次预警job锁
        String redisKey = Constants.EQUIPMENT_WARNING_AGAIN;
        try {
            Boolean acquire = redisUtil.setIfAbsent(redisKey, String.valueOf(System.currentTimeMillis()), Constants.TIME_OUT);//15分钟超时
            if (acquire) {
                try {
                    List<String> keys = getKeys(redisTemplate, patternKey);
                    if (!CollectionUtil.isEmpty(keys)) {
                        log.info("warnStrategyAgain-本次扫描到需要执行的数据：{}", JSONObject.toJSONString(keys));
                        //进行再次预警
                        for (String key : keys) {
                                redisCache.deleteObject(key);
                        }
                    }
                } catch (NumberFormatException e) {
                    log.info("warnStrategyAgain-error:{}", e);
                } finally {
                    redisUtil.del(redisKey);
                }
            }
        } catch (Exception e) {
            log.info("warnStrategyAgain-error:{}", e);
        }
        log.info("warnStrategyAgain--end--------");
        XxlJobLogger.log("XXLJOB-warnStrategyAgain end..." );
        return ReturnT.SUCCESS;
    }

    public static List<String> getKeys(RedisTemplate redisTemplate, String patternKey) {
        long start = System.currentTimeMillis();
        List<String> result = new ArrayList<>();
        try {
            ScanOptions options = ScanOptions.scanOptions()
                .count(1000)
                .match(patternKey).build();
            RedisSerializer<String> redisSerializer = (RedisSerializer<String>) redisTemplate.getKeySerializer();
            Cursor cursor = (Cursor) redisTemplate.executeWithStickyConnection(redisConnection ->
                    new ConvertingCursor<>(redisConnection.scan(options), redisSerializer::deserialize));
            while (cursor.hasNext()) {
                result.add(cursor.next().toString());
            }
            cursor.close();
        } catch (IOException e) {
            log.error("getKeys-error:{}", e);
            return result;
        }
        log.info("scan扫描共耗时：{} ms key数量：{}", System.currentTimeMillis() - start, result.size());
        return result;
    }

    public void deleteCache(String key, String imei, String identificationCode, String alarmStrategykey) {
        redisCache.deleteObject(key);
        log.info("warnStrategyAgain-删除队列中的key：{}", key);
        //更新数据
        warningRecordService.updateRecordStatus(imei, identificationCode, 2);
        //删除策略执行次数key
        redisCache.deleteObject(Constants.ALARM_STRATEGY + alarmStrategykey);
        log.info("warnStrategyAgain-删除队列中的策略计数key：{}", "alarm_strategy" + alarmStrategykey);
    }


}
